package preprocess;

import static utils.Configuration.getAttribute;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Hashtable;

import org.apache.commons.io.FileUtils;

/**
 * @author huangcd
 * 
 */
@SuppressWarnings("unused")
public class TestSetGenerator
{
    private static int                         totalType = 16;
    private static int                         minSize   = 5 * 1024;
    private static int                         maxSize   = 20 * 1024;
    private static int[]                       type;
    private static int[]                       count;
    private static String                      setLocation;
    private static File[]                      directions;
    private static Hashtable<Integer, Integer> typeCount;

    public static void init()
    {
        type = new int[totalType];
        count = new int[totalType];
        // setLocation = getAttribute(DATA, "train_set");
        typeCount = new Hashtable<Integer, Integer>();
        File root = new File(setLocation);
        directions = root.listFiles(new FileFilter()
        {
            @Override
            public boolean accept(File path)
            {
                return path.isDirectory();
            }
        });
        for (File direction : directions)
        {
            int t = Integer.parseInt(direction.getName());
            int c = direction.listFiles().length * 2;
            typeCount.put(t, c);
        }
        Integer[] tmp = typeCount.keySet().toArray(new Integer[0]);
        Arrays.sort(tmp, new Comparator<Integer>()
        {
            Hashtable<Integer, Integer> table;

            @Override
            public int compare(Integer o1, Integer o2)
            {
                return -table.get(o1).compareTo(table.get(o2));
            }

            public Comparator<Integer> setTable(Hashtable<Integer, Integer> t)
            {
                table = t;
                return this;
            }
        }.setTable(typeCount));
        directions = new File[totalType];
        for (int i = 0; i < totalType; i++)
        {
            type[i] = tmp[i];
            count[i] = typeCount.get(tmp[i]);
            directions[i] = new File(setLocation + "/" + type[i]);
        }
    }

    public static void generatorSets(boolean sameSetSize, int setCount,
            int totalCount, File outputDirection)
    {
        Hashtable<File, Integer> dirMap = new Hashtable<File, Integer>();
        int i = setCount;
        double filesCount = 0;
        while (i > 0)
        {
            if ((i % 2) == 0)
            {
                int index = (setCount - i) / 2;
                dirMap.put(directions[index], count[index]);
                filesCount += count[index];
                index = totalType / 2 + index;
                dirMap.put(directions[index], count[index]);
                filesCount += count[index];
                i -= 2;
            }
            else
            {
                int index = (setCount - i) / 2;
                dirMap.put(directions[index], count[index]);
                filesCount += count[index];
                i -= 1;
            }
        }
        if (sameSetSize)
        {
            int setSize = totalCount / setCount;
            for (File direction : dirMap.keySet())
            {
                saveXMLs(outputDirection, setSize, direction);
            }
        }
        else
        {
            for (File direction : dirMap.keySet())
            {
                int setSize = (int) (dirMap.get(direction) / filesCount * totalCount);
                saveXMLs(outputDirection, setSize, direction);
            }
        }
    }

    private static void saveXMLs(File outputDirection, int setSize,
            File direction)
    {
        File[] xmls = direction.listFiles(new FileFilter()
        {
            @Override
            public boolean accept(File file)
            {
                if (file.getName().toLowerCase().endsWith(".xml"))
                {
                    if (file.length() < maxSize) { return true; }
                }
                return false;
            }
        });
        Arrays.sort(xmls, new Comparator<File>()
        {
            @Override
            public int compare(File f1, File f2)
            {
                return (int) (-f1.length() + f2.length());
            }
        });
        xmls = Arrays.copyOf(xmls, setSize);
        String path = outputDirection.getAbsolutePath() + "/"
                + direction.getName() + "/";
        System.out.println(path);
        for (File xml : xmls)
        {
            try
            {
                FileUtils.copyFile(xml, new File(path + "/"
                        + direction.getName() + "_" + xml.getName()));
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * @return the totalType
     */
    public static int getTotalType()
    {
        return totalType;
    }

    /**
     * @param totalType
     *            the totalType to set
     */
    public static void setTotalType(int totalType)
    {
        TestSetGenerator.totalType = totalType;
    }

    /**
     * @return the setLocation
     */
    public static String getSetLocation()
    {
        return setLocation;
    }

    /**
     * @param setLocation
     *            the setLocation to set
     */
    public static void setSetLocation(String setLocation)
    {
        TestSetGenerator.setLocation = setLocation;
    }

    public static void main(String[] args)
    {
        // setSetLocation(getAttribute(DATA, "train_set"));
        // init();
        // generatorSets(true, 2, 400, new File("D:/INEX Dataset/same_size_2"));
        // generatorSets(true, 4, 800, new File("D:/INEX Dataset/same_size_4"));
        // generatorSets(true, 8, 1600, new
        // File("D:/INEX Dataset/same_size_8"));
        // generatorSets(true, 16, 3200, new
        // File("D:/INEX Dataset/same_size_16"));
        //
        // generatorSets(false, 2, 400, new File(
        // "D:/INEX Dataset/different_size_2"));
        // generatorSets(false, 4, 800, new File(
        // "D:/INEX Dataset/different_size_4"));
        // generatorSets(false, 8, 1600, new File(
        // "D:/INEX Dataset/different_size_8"));
        // generatorSets(false, 16, 3200, new File(
        // "D:/INEX Dataset/different_size_16"));
    }
}
